/**
 * MySQL EXPLAIN 可视化工具主应用
 */
class ExplainApp {
    constructor() {
        this.parser = new ExplainParser();
        this.visualizer = new ExplainVisualizer('graphContainer');
        this.currentTheme = 'light';
        
        this.init();
    }

    /**
     * 初始化应用
     */
    init() {
        this.initializeElements();
        this.bindEvents();
        this.loadTheme();
        this.initBackgroundAnimation();
        this.initializeFormatTabs();
        this.showState('empty');
    }

    /**
     * 初始化格式选择器
     */
    initializeFormatTabs() {
        this.currentFormat = 'auto';
        this.switchFormat('auto');
    }

    /**
     * 初始化DOM元素
     */
    initializeElements() {
        this.elements = {
            // 输入相关
            formatSelector: document.getElementById('formatSelector'),
            formatDisplay: document.getElementById('formatDisplay'),
            copyFormatBtn: document.getElementById('copyFormatBtn'),
            explainInput: document.getElementById('explainInput'),
            fileInput: document.getElementById('fileInput'),
            fileUploadArea: document.getElementById('fileUploadArea'),
            formatIndicator: document.getElementById('formatIndicator'),
            
            // 按钮
            parseBtn: document.getElementById('parseBtn'),
            clearBtn: document.getElementById('clearBtn'),
            exampleBtn: document.getElementById('exampleBtn'),
            pasteBtn: document.getElementById('pasteBtn'),
            themeSelector: document.getElementById('themeSelector'),
            panelToggleBtn: document.getElementById('panelToggleBtn'),
            floatingInputPanel: document.getElementById('floatingInputPanel'),
            
            // 可视化控制
            resetViewBtn: document.getElementById('resetViewBtn'),
            zoomInBtn: document.getElementById('zoomInBtn'),
            zoomOutBtn: document.getElementById('zoomOutBtn'),
            exportPngBtn: document.getElementById('exportPngBtn'),
            exportJsonBtn: document.getElementById('exportJsonBtn'),
            
            // 状态显示
            loadingState: document.getElementById('loadingState'),
            emptyState: document.getElementById('emptyState'),
            errorState: document.getElementById('errorState'),
            errorMessage: document.getElementById('errorMessage'),
            
            // 节点详情
            nodeDetails: document.getElementById('nodeDetails'),
            closeDetailsBtn: document.getElementById('closeDetailsBtn'),
            
            // 示例模态框
            exampleModal: document.getElementById('exampleModal'),
            closeExampleModal: document.getElementById('closeExampleModal'),
            exampleTabs: document.querySelectorAll('.tab-btn'),
            exampleContent: document.getElementById('exampleContent'),
            useExampleBtn: document.getElementById('useExampleBtn'),
            cancelExampleBtn: document.getElementById('cancelExampleBtn')
        };
    }

    /**
     * 绑定事件
     */
    bindEvents() {
        // 解析按钮
        this.elements.parseBtn.addEventListener('click', () => this.handleParse());
        
        // 清空按钮
        this.elements.clearBtn.addEventListener('click', () => this.handleClear());
        
        // 示例按钮
        this.elements.exampleBtn.addEventListener('click', () => this.showExampleModal());
        
        // 粘贴按钮
        this.elements.pasteBtn.addEventListener('click', () => this.handlePaste());
        
        // 格式选择器切换
        this.elements.formatSelector.addEventListener('change', (e) => this.switchFormat(e.target.value));
        
        // 复制格式按钮
        this.elements.copyFormatBtn.addEventListener('click', () => this.copyFormatCommand());
        
        // 主题切换
        this.elements.themeSelector.addEventListener('change', (e) => this.changeTheme(e.target.value));
        
        // 面板切换
        this.elements.panelToggleBtn.addEventListener('click', () => this.toggleInputPanel());
        
        // 可视化控制按钮
        this.elements.resetViewBtn.addEventListener('click', () => this.visualizer.resetView());
        this.elements.zoomInBtn.addEventListener('click', () => this.visualizer.zoomIn());
        this.elements.zoomOutBtn.addEventListener('click', () => this.visualizer.zoomOut());
        this.elements.exportPngBtn.addEventListener('click', () => this.visualizer.exportPNG());
        this.elements.exportJsonBtn.addEventListener('click', () => this.visualizer.exportJSON());
        
        // 悬浮按钮事件
        document.getElementById('floatingResetBtn').addEventListener('click', () => this.visualizer.resetView());
        document.getElementById('floatingZoomInBtn').addEventListener('click', () => this.visualizer.zoomIn());
        document.getElementById('floatingZoomOutBtn').addEventListener('click', () => this.visualizer.zoomOut());
        document.getElementById('floatingExportPngBtn').addEventListener('click', () => this.visualizer.exportPNG());
        document.getElementById('floatingExportJsonBtn').addEventListener('click', () => this.visualizer.exportJSON());
        
        // 文件上传
        this.elements.fileInput.addEventListener('change', (e) => this.handleFileUpload(e));
        this.elements.fileUploadArea.addEventListener('click', () => this.elements.fileInput.click());
        
        // 拖拽上传
        this.elements.fileUploadArea.addEventListener('dragover', (e) => {
            e.preventDefault();
            this.elements.fileUploadArea.style.borderColor = 'var(--accent-color)';
        });
        
        this.elements.fileUploadArea.addEventListener('dragleave', (e) => {
            e.preventDefault();
            this.elements.fileUploadArea.style.borderColor = 'var(--border-color)';
        });
        
        this.elements.fileUploadArea.addEventListener('drop', (e) => {
            e.preventDefault();
            this.elements.fileUploadArea.style.borderColor = 'var(--border-color)';
            this.handleFileDrop(e);
        });
        
        // 节点详情关闭
        this.elements.closeDetailsBtn.addEventListener('click', () => {
            this.elements.nodeDetails.classList.add('hidden');
        });
        
        // 示例模态框
        this.elements.closeExampleModal.addEventListener('click', () => this.hideExampleModal());
        this.elements.cancelExampleBtn.addEventListener('click', () => this.hideExampleModal());
        this.elements.useExampleBtn.addEventListener('click', () => this.useExample());
        
        // 示例标签切换
        this.elements.exampleTabs.forEach(tab => {
            tab.addEventListener('click', (e) => this.switchExampleTab(e.target.dataset.format));
        });
        
        // 模态框背景点击关闭
        this.elements.exampleModal.addEventListener('click', (e) => {
            if (e.target === this.elements.exampleModal) {
                this.hideExampleModal();
            }
        });
        
        // 快捷键
        document.addEventListener('keydown', (e) => this.handleKeyboard(e));
        
        // 输入框变化（添加防抖处理）
        let inputTimeout;
        this.elements.explainInput.addEventListener('input', () => {
            clearTimeout(inputTimeout);
            inputTimeout = setTimeout(() => {
                const hasContent = this.elements.explainInput.value.trim().length > 0;
                this.elements.parseBtn.disabled = !hasContent;
                this.elements.clearBtn.disabled = !hasContent;
                
                // 更新格式指示器
                this.updateFormatIndicator();
            }, 300);
        });
    }

    /**
     * 处理解析
     */
    async handleParse() {
        const input = this.elements.explainInput.value.trim();
        
        if (!input) {
            this.showError('请输入 EXPLAIN 数据');
            return;
        }

        // 检查输入大小限制（1MB）
        if (input.length > 1024 * 1024) {
            this.showError('输入数据过大，请确保小于1MB');
            return;
        }

        try {
            this.showState('loading');
            this.elements.parseBtn.disabled = true;
            
            // 使用 requestIdleCallback 进行异步处理，避免阻塞UI
            await new Promise((resolve, reject) => {
                const processData = () => {
                    try {
                        // 解析数据，传入当前选择的格式
                        const result = this.parser.parse(input, this.currentFormat);
                        
                        // 渲染可视化
                        this.visualizer.render(result);
                        
                        resolve(result);
                    } catch (error) {
                        reject(error);
                    }
                };

                if (window.requestIdleCallback) {
                    window.requestIdleCallback(processData, { timeout: 5000 });
                } else {
                    setTimeout(processData, 0);
                }
            });
            
            this.showState('success');
            
        } catch (error) {
            console.error('解析错误:', error);
            this.showError(this.getFriendlyErrorMessage(error.message));
        } finally {
            this.elements.parseBtn.disabled = false;
        }
    }

    /**
     * 获取友好的错误消息
     */
    getFriendlyErrorMessage(errorMessage) {
        const errorMap = {
            '输入数据不能为空': '请输入 EXPLAIN 数据',
            '无法识别的EXPLAIN格式': '输入格式不正确，请检查数据是否为有效的 EXPLAIN 输出',
            'JSON格式解析失败': 'JSON 格式错误，请检查数据完整性',
            'Unexpected token': 'JSON 格式错误，请检查语法',
            'Container': '图形容器初始化失败，请刷新页面重试'
        };

        for (const [key, message] of Object.entries(errorMap)) {
            if (errorMessage.includes(key)) {
                return message;
            }
        }

        return errorMessage || '解析失败，请检查输入数据';
    }

    /**
     * 处理清空
     */
    handleClear() {
        this.elements.explainInput.value = '';
        this.switchFormat('auto');
        this.elements.parseBtn.disabled = true;
        this.elements.clearBtn.disabled = true;
        this.elements.nodeDetails.classList.add('hidden');
        this.showState('empty');
        
        // 清除图表
        if (this.visualizer && this.visualizer.graph) {
            this.visualizer.graph.clear();
        }
        
        // 重置统计信息
        if (this.visualizer) {
            this.visualizer.updateStats({
                totalCost: 0,
                nodeCount: 0,
                executionTime: null,
                rowsExamined: 0
            });
        }
        
        // 重置解析器
        this.parser.resetNodeIdCounter();
    }

    /**
     * 切换格式
     */
    switchFormat(format, isAutoDetected = false) {
        // 更新选择器状态
        this.elements.formatSelector.value = format;
        
        // 存储当前选择的格式
        this.currentFormat = format;
        
        // 更新格式显示框
        this.updateFormatDisplay(format);
        
        // 更新输入框占位符
        this.updateInputPlaceholder(format);
        
        // 如果是自动检测的，显示提示
        if (isAutoDetected && format !== 'auto') {
            this.showFormatDetectionNotification(format);
        }
        
        // 如果有内容，可能需要重新解析
        if (this.elements.explainInput.value.trim()) {
            // 可以添加自动重新解析逻辑
        }
    }

    /**
     * 更新格式显示框
     */
    updateFormatDisplay(format) {
        const formatCommands = {
            auto: '',
            tree: 'EXPLAIN FORMAT=TREE',
            json: 'EXPLAIN FORMAT=JSON',
            traditional: 'EXPLAIN'
        };
        
        this.elements.formatDisplay.value = formatCommands[format] || '';
    }

    /**
     * 复制格式命令
     */
    async copyFormatCommand() {
        try {
            if (!navigator.clipboard) {
                throw new Error('剪贴板API不可用');
            }
            
            const command = this.elements.formatDisplay.value;
            if (!command.trim()) {
                this.showTemporaryMessage('自动检测模式无需特定格式命令');
                return;
            }
            
            await navigator.clipboard.writeText(command);
            
            // 显示复制成功提示
            this.showTemporaryMessage('格式命令已复制到剪贴板');
            
            // 临时改变按钮样式表示成功
            const copyIcon = this.elements.copyFormatBtn.querySelector('.copy-icon');
            const originalIcon = copyIcon.textContent;
            copyIcon.textContent = '✓';
            setTimeout(() => {
                copyIcon.textContent = originalIcon;
            }, 1000);
            
        } catch (error) {
            this.showError('复制失败: ' + error.message);
        }
    }

    /**
     * 显示临时消息
     */
    showTemporaryMessage(message) {
        // 创建临时提示元素
        const notification = document.createElement('div');
        notification.className = 'temporary-notification';
        notification.textContent = message;
        notification.style.cssText = `
            position: fixed;
            top: 100px;
            right: 20px;
            background: var(--bg-glass);
            backdrop-filter: var(--glass-blur);
            -webkit-backdrop-filter: var(--glass-blur);
            border: 1px solid var(--border-glass);
            border-radius: 8px;
            padding: 0.5rem 1rem;
            color: var(--text-primary);
            box-shadow: var(--glass-shadow);
            z-index: 1000;
            opacity: 0;
            transform: translateX(100%);
            transition: all 0.3s ease;
            font-size: 0.8rem;
        `;
        
        document.body.appendChild(notification);
        
        // 动画显示
        requestAnimationFrame(() => {
            notification.style.opacity = '1';
            notification.style.transform = 'translateX(0)';
        });
        
        // 3秒后移除
        setTimeout(() => {
            notification.style.opacity = '0';
            notification.style.transform = 'translateX(100%)';
            setTimeout(() => {
                if (notification.parentNode) {
                    notification.parentNode.removeChild(notification);
                }
            }, 300);
        }, 3000);
    }

    /**
     * 显示格式检测通知
     */
    showFormatDetectionNotification(detectedFormat) {
        const formatNames = {
            json: 'JSON',
            tree: 'Tree',
            traditional: 'Traditional'
        };
        
        const message = `检测到 ${formatNames[detectedFormat]} 格式，已重置为${formatNames[detectedFormat]} 格式`;
        this.showTemporaryMessage(message);
    }

    /**
     * 更新输入框占位符
     */
    updateInputPlaceholder(format) {
        const placeholders = {
            auto: '请粘贴 MySQL EXPLAIN 输出结果...',
            tree: '请粘贴 Tree 格式的 EXPLAIN 输出结果...',
            json: '请粘贴 JSON 格式的 EXPLAIN 输出结果...',
            traditional: '请粘贴 Traditional 格式的 EXPLAIN 输出结果...'
        };
        
        this.elements.explainInput.placeholder = placeholders[format] || placeholders.auto;
    }

    /**
     * 处理粘贴功能
     */
    async handlePaste() {
        try {
            if (!navigator.clipboard) {
                throw new Error('剪贴板API不可用');
            }
            
            const text = await navigator.clipboard.readText();
            if (text.trim()) {
                this.elements.explainInput.value = text;
                this.elements.parseBtn.disabled = false;
                this.elements.clearBtn.disabled = false;
                
                // 更新格式指示器
                this.updateFormatIndicator();
                
                // 聚焦到输入框
                this.elements.explainInput.focus();
            } else {
                this.showError('剪贴板为空或无文本内容');
            }
        } catch (error) {
            this.showError('粘贴失败: ' + error.message);
        }
    }

    /**
     * 简单的格式检测
     */
    detectFormat(text) {
        const trimmed = text.trim();
        
        // 检测JSON格式
        if (trimmed.startsWith('{') || trimmed.startsWith('[')) {
            try {
                JSON.parse(trimmed);
                return 'json';
            } catch (e) {
                // 不是有效的JSON
            }
        }
        
        // 检测Tree格式 - 通常包含特定的树状字符
        if (trimmed.includes('-> ') || trimmed.includes('└─') || trimmed.includes('├─')) {
            return 'tree';
        }
        
        // 检测Traditional格式 - 通常包含表格头或特定的列
        if (trimmed.includes('select_type') || trimmed.includes('table') || trimmed.includes('type')) {
            return 'traditional';
        }
        
        return 'auto';
    }

    /**
     * 更新格式指示器
     */
    updateFormatIndicator() {
        const input = this.elements.explainInput.value.trim();
        const indicatorIcon = this.elements.formatIndicator.querySelector('.indicator-icon');
        const indicatorText = this.elements.formatIndicator.querySelector('.indicator-text');
        
        // 清除之前的状态类
        this.elements.formatIndicator.classList.remove('detected', 'error');
        
        if (!input) {
            indicatorIcon.textContent = '🔍';
            indicatorText.textContent = '等待输入数据';
            return;
        }
        
        try {
            const detectedFormat = this.detectFormat(input);
            
            if (detectedFormat !== 'auto') {
                this.elements.formatIndicator.classList.add('detected');
                
                const formatInfo = {
                    json: { icon: '📋', text: '检测到 JSON 格式' },
                    tree: { icon: '🌳', text: '检测到 Tree 格式' },
                    traditional: { icon: '📊', text: '检测到 Traditional 格式' }
                };
                
                const info = formatInfo[detectedFormat];
                if (info) {
                    indicatorIcon.textContent = info.icon;
                    indicatorText.textContent = info.text;
                }
                
                // 如果当前选择的是自动检测，则自动切换格式
                if (this.currentFormat === 'auto') {
                    this.switchFormat(detectedFormat, true);
                } else if (this.currentFormat !== detectedFormat) {
                    // 如果手动选择了不同的类别，自动切换并提示
                    this.switchFormat(detectedFormat, true);
                }
            } else {
                indicatorIcon.textContent = '❓';
                indicatorText.textContent = '格式未识别';
            }
        } catch (error) {
            this.elements.formatIndicator.classList.add('error');
            indicatorIcon.textContent = '❌';
            indicatorText.textContent = '格式错误';
        }
    }

    /**
     * 处理文件上传
     */
    async handleFileUpload(event) {
        const files = event.target.files;
        if (!files || files.length === 0) return;
        
        try {
            const file = files[0];
            const content = await this.readFile(file);
            this.elements.explainInput.value = content;
            this.elements.parseBtn.disabled = false;
            this.elements.clearBtn.disabled = false;
            
            // 更新格式指示器
            this.updateFormatIndicator();
            
            // 根据文件扩展名设置格式
            const extension = file.name.split('.').pop().toLowerCase();
            if (extension === 'json') {
                this.switchFormat('json');
            }
            
        } catch (error) {
            this.showError('文件读取失败: ' + error.message);
        }
    }

    /**
     * 处理文件拖拽
     */
    async handleFileDrop(event) {
        const files = event.dataTransfer.files;
        if (!files || files.length === 0) return;
        
        try {
            const file = files[0];
            const content = await this.readFile(file);
            this.elements.explainInput.value = content;
            this.elements.parseBtn.disabled = false;
            this.elements.clearBtn.disabled = false;
            
            // 更新格式指示器
            this.updateFormatIndicator();
            
            // 根据文件扩展名设置格式
            const extension = file.name.split('.').pop().toLowerCase();
            if (extension === 'json') {
                this.switchFormat('json');
            }
            
        } catch (error) {
            this.showError('文件读取失败: ' + error.message);
        }
    }

    /**
     * 读取文件内容
     */
    readFile(file) {
        return new Promise((resolve, reject) => {
            const reader = new FileReader();
            reader.onload = (e) => resolve(e.target.result);
            reader.onerror = () => reject(new Error('文件读取失败'));
            reader.readAsText(file);
        });
    }

    /**
     * 显示示例模态框
     */
    showExampleModal() {
        this.elements.exampleModal.classList.remove('hidden');
        this.switchExampleTab('tree'); // 默认显示tree格式
    }

    /**
     * 隐藏示例模态框
     */
    hideExampleModal() {
        this.elements.exampleModal.classList.add('hidden');
    }

    /**
     * 切换示例标签
     */
    switchExampleTab(format) {
        // 更新标签状态
        this.elements.exampleTabs.forEach(tab => {
            tab.classList.toggle('active', tab.dataset.format === format);
        });
        
        // 更新示例内容
        this.elements.exampleContent.textContent = EXAMPLE_DATA[format] || '';
    }

    /**
     * 使用示例数据
     */
    useExample() {
        const activeTab = document.querySelector('.tab-btn.active');
        const format = activeTab.dataset.format;
        
        this.elements.explainInput.value = EXAMPLE_DATA[format];
        this.switchFormat(format);
        this.elements.parseBtn.disabled = false;
        this.elements.clearBtn.disabled = false;
        
        this.hideExampleModal();
    }

    /**
     * 切换主题
     */
    changeTheme(theme) {
        this.currentTheme = theme;
        document.body.setAttribute('data-theme', theme);
        
        // 更新选择器值
        this.elements.themeSelector.value = theme;
        
        // 保存主题设置
        localStorage.setItem('explainTheme', theme);
        
        // 更新背景动画
        this.updateBackgroundAnimation();
        
        // 添加切换动画效果
        document.body.style.transition = 'all 0.5s ease';
        setTimeout(() => {
            document.body.style.transition = '';
        }, 500);
    }

    /**
     * 切换输入面板的显示/隐藏状态
     */
    toggleInputPanel() {
        const panel = this.elements.floatingInputPanel;
        const toggleBtn = this.elements.panelToggleBtn;
        
        if (panel.classList.contains('collapsed')) {
            // 展开面板
            panel.classList.remove('collapsed');
            toggleBtn.textContent = '−';
            toggleBtn.title = '收起输入面板';
        } else {
            // 收起面板
            panel.classList.add('collapsed');
            toggleBtn.textContent = '+';
            toggleBtn.title = '展开输入面板';
        }
    }

    /**
     * 初始化背景动画
     */
    initBackgroundAnimation() {
        this.animatedBackground = document.getElementById('animatedBackground');
        this.updateBackgroundAnimation();
    }

    /**
     * 更新背景动画状态
     */
    updateBackgroundAnimation() {
        if (!this.animatedBackground) return;
        
        // 只在科技主题下显示和控制动画
        if (this.currentTheme === 'tech') {
            this.animatedBackground.style.display = 'block';
            
            const squares = this.animatedBackground.querySelectorAll('.floating-square');
            
            // 根据科技主题调整动画强度
            squares.forEach((square, index) => {
                const animationDuration = this.getAnimationDuration(index);
                square.style.animationDuration = animationDuration;
                
                // 设置科技主题的透明度
                const opacity = this.getSquareOpacity();
                square.style.opacity = opacity;
            });
        } else {
            // 其他主题隐藏动画
            this.animatedBackground.style.display = 'none';
        }
    }

    /**
     * 获取动画持续时间（仅科技主题使用）
     */
    getAnimationDuration(index) {
        const techDurations = ['12s', '15s', '16s', '18s', '13s', '16s', '17s', '14s'];
        return techDurations[index] || '15s';
    }

    /**
     * 获取方框透明度（仅科技主题使用）
     */
    getSquareOpacity() {
        return '0.15';
    }

    /**
     * 加载主题设置
     */
    loadTheme() {
        const savedTheme = localStorage.getItem('explainTheme') || 'light';
        this.currentTheme = savedTheme;
        document.body.setAttribute('data-theme', this.currentTheme);
        this.elements.themeSelector.value = this.currentTheme;
    }

    /**
     * 处理键盘事件
     */
    handleKeyboard(event) {
        // Ctrl/Cmd + Enter 解析
        if ((event.ctrlKey || event.metaKey) && event.key === 'Enter') {
            event.preventDefault();
            if (!this.elements.parseBtn.disabled) {
                this.handleParse();
            }
        }
        
        // Escape 关闭模态框和详情面板
        if (event.key === 'Escape') {
            this.hideExampleModal();
            this.elements.nodeDetails.classList.add('hidden');
        }
    }

    /**
     * 显示状态
     */
    showState(state) {
        // 隐藏所有状态
        this.elements.loadingState.classList.add('hidden');
        this.elements.emptyState.classList.add('hidden');
        this.elements.errorState.classList.add('hidden');
        
        // 显示指定状态
        switch (state) {
            case 'loading':
                this.elements.loadingState.classList.remove('hidden');
                break;
            case 'empty':
                this.elements.emptyState.classList.remove('hidden');
                break;
            case 'error':
                this.elements.errorState.classList.remove('hidden');
                break;
            case 'success':
                // 成功时不显示任何状态覆盖层
                break;
        }
    }

    /**
     * 显示错误
     */
    showError(message) {
        this.elements.errorMessage.textContent = message;
        this.showState('error');
    }

    /**
     * 显示成功消息
     */
    showSuccess(message) {
        // 可以在这里添加成功提示
        console.log('Success:', message);
    }
}

// 页面加载完成后初始化应用
document.addEventListener('DOMContentLoaded', () => {
    window.explainApp = new ExplainApp();
});

// 导出
window.ExplainApp = ExplainApp;
